#include "tcpserver.h"
#include <signal.h>

Tcpserver tcpServer;
void FathEXIT(int sig);   // 父进程的信号处理函数
void ChildEXIT(int sig);   // 子进程的信号处理函数

/*
    多进程中
        父进程只受理客户端的连接，不与客户端通讯
        子进程负责与客户端通讯，不受理客户端的连接
        fork之后，父进程不需要clientfd，子进程不需要serverfd
*/

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        std::cout << "Usage: ./server port" << std::endl;
        return -1;
    }

    // 忽略全部的信号
    for (int i = 0; i < 64; i++)
    {
        signal(i, SIG_IGN);
    }

    // 设置信号，在shell下可用kill 进程号或ctrl C终止进程
    signal(SIGTERM, FathEXIT);
    signal(SIGINT, FathEXIT);   // SIGTERM 15 SIGINT 2
    
    tcpServer.initServer(std::atoi(argv[1]));

    while (true)
    {
        bool flag;
        // 4、受理客户的连接请求,从已连接的客户端中取出一个客户端
        // 如果没有客户连接，则accept函数已知阻塞
        flag = tcpServer.accept();
        if (!flag)
        {
            std::cout << "accept err" << std::endl;
            return -1;
        }

        int pid = fork();
        if(pid == -1)
        {
            std::cout << "fork err" << std::endl;
            return -1;
        }
        if (pid >0)
        {
            tcpServer.closeClientFD();   // 关闭客户端连接的socket
            continue;  // 父进程从循环开始重新执行，受理客户端的连接
        }

        tcpServer.closeServerFD(); // 子进程关闭监听的socket

        // 子进程需要重新设置信号
        signal(SIGTERM, ChildEXIT);   // 子进程的退出函数与父进程不一样
        signal(SIGINT, SIG_IGN);    // 子进程不需要捕获SIGINT信号
        
        // 子进程负责和客户端通信
        std::cout << "客户已连接,ip=" << tcpServer.clientIp << std::endl;

        // 5、与客户端通信，接受客户端发过来的报文后，回复ok
        std::string buffer;
        while (true)
        {
            flag = tcpServer.recv(buffer, 1024);
            if (!flag)
            {
                std::cout << "recv err";
                break;
            }
            std::cout << "接收:" << buffer << std::endl;
            sleep(1);
            buffer = "ok"; // 生成回应报文
            // 向客户发送回应报文
            flag = tcpServer.send(buffer);
            if (!flag)
            {
                std::cout << "send error";
                break;
            }
            std::cout << "发送:" << buffer << std::endl;
        }
    }
    
    return 0;
}

void FathEXIT(int sig)
{
    // 防止信号处理函数在执行的过程中再次被信号中断
    signal(SIGINT, SIG_IGN);
    signal(SIGTERM,  SIG_IGN);

    std::cout << "父进程退出，sig=" << sig << std::endl;

    kill(0, SIGTERM);  // 向全部子进程发送15的信号，通知退出

    // 释放全局资源
    tcpServer.closeServerFD();

    exit(0);
}
void ChildEXIT(int sig)
{
    // 防止信号处理函数在执行的过程中再次被信号中断
    signal(SIGINT, SIG_IGN);
    signal(SIGTERM,  SIG_IGN);

    std::cout << "子进程" << getpid() << "退出,sig=" << sig << std::endl;

    // 释放子进程资源
    tcpServer.closeClientFD();

    exit(0);
}

